﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace CrazyMan.TM.Interface.Domain
{
    /// <summary>
    /// Represents a bank of chips.
    /// </summary>
    [DebuggerDisplay("${Chip.Value}; Total {Total}; Available {Available}")]
    public class ChipBank
    {
        private Chip _chip;
        private int _total;
        private int _widthdrawn;

        /// <summary>
        /// Creates a new chip bank with the specified number of chips.
        /// </summary>
        /// <param name="chip">The type of chip the bank will hold.</param>
        /// <param name="total">The total number of chips in the bank.</param>
        public ChipBank(Chip chip, int total)
        {
            ValidateChipCount(total);

            this._chip = chip;
            this._total = total;
        }

        /// <summary>
        /// Gets the chip in the bank.
        /// </summary>
        public Chip Chip
        {
            get { return this._chip; }
        }

        /// <summary>
        /// Gets the total number of chips in the bank.
        /// </summary>
        public int Total
        {
            get { return this._total; }
        }

        /// <summary>
        /// Gets the number of chips available in the bank.
        /// </summary>
        public int Available
        {
            get { return (this._total - this._widthdrawn); }
        }

        /// <summary>
        /// Withdraws a specified number of chips from the bank.
        /// </summary>
        /// <param name="count">The number of chips to withdraw from the bank.</param>
        public void Withdraw(int count)
        {
            if (count < 0)
                throw new ArgumentOutOfRangeException("count", "Can not withdraw a negative number of chips.");

            if (count > Available)
                throw new ArgumentException("count", "There are not enough chips available in the bank.");

            this._widthdrawn += count;
        }

        /// <summary>
        /// Desposits a specified number of chips into the bank.
        /// </summary>
        /// <param name="count">The number of chips to deposit into the bank.</param>
        public void Deposit(int count)
        {
            if (count < 0)
                throw new ArgumentOutOfRangeException("count", "Can not deposit a negative number of chips.");

            if (count > _widthdrawn)
                throw new ArgumentException("count", "Can not deposit more chips than have been withdrawn from the bank.");

            this._widthdrawn -= count;
        }

        /// <summary>
        /// Validates that the chip count is legal.
        /// </summary>
        /// <param name="chipCount">The chip count to be validated.</param>
        protected void ValidateChipCount(int chipCount)
        {
            if (chipCount < 0)
                throw new ArgumentOutOfRangeException("chipCount", "The chip count can not be negative.");
        }
    }
}
